
/********************************************************************************************************
*
* File                : UART.C
*
*********************************************************************************************************/






/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"

#include "common.h"
#include "delay.h"




#if 0

/* Private define ------------------------------------------------------------*/

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */


PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData(USART1, (uint8_t) ch);
	//USART_SendData(USART1,(u8)ch);

  /* Loop until the end of transmission */
  while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
	//while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
  {}

  return ch;
}

#endif



/**********************************************************************
    UART 
**********************************************************************/
/* type definition */

//#define USART1                   USART1
#define USART1_GPIO              GPIOA
#define USART1_CLK               RCC_APB2Periph_USART1
#define USART1_GPIO_CLK          RCC_APB2Periph_GPIOA
#define USART1_RxPin             GPIO_Pin_10
#define USART1_TxPin             GPIO_Pin_9
//#define USART1_Tx_DMA_Channel    DMA1_Channel4
//#define USART1_Tx_DMA_FLAG       DMA1_FLAG_TC4
#define USART1_DR_Base           0x40013804


//#define USART2                   USART2
#define USART2_GPIO              GPIOA
#define USART2_CLK               RCC_APB1Periph_USART2
#define USART2_GPIO_CLK          RCC_APB2Periph_GPIOA
#define USART2_RxPin             GPIO_Pin_3
#define USART2_TxPin             GPIO_Pin_2
//#define USART2_Tx_DMA_Channel    DMA1_Channel7
//#define USART2_Tx_DMA_FLAG       DMA1_FLAG_TC7
#define USART2_Rx_DMA_Channel    DMA1_Channel6
#define USART2_Rx_DMA_FLAG       DMA1_FLAG_TC6  
#define USART2_DR_Base           0x40004404


/* Private variables */
uint8_t UART1_Rx_Buffer[100];
uint8_t UART2_Rx_Buffer[100];

/* functions */


/* -----------------------------------------------------------------------------
USART_Configuration
-------------------------------------------------------------------------------*/
void USART1_init(void)
{

DMA_InitTypeDef  DMA_InitStructure;
USART_InitTypeDef USART_InitStructure; 
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef  NVIC_InitStructure;




    
#if 1
        /* DMA1 clock enable */
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    
    
    
//        DMA_InitTypeDef  DMA_InitStructure;
    
        /* USART1_RX_DMA1_Channel Config */
        DMA_DeInit(DMA1_Channel5);
        DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;
        DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)UART1_Rx_Buffer;
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
        DMA_InitStructure.DMA_BufferSize = sizeof(UART1_Rx_Buffer);
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
#if 0
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
#else
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
#endif
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
        DMA_InitStructure.DMA_Priority = DMA_Priority_High;
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
        DMA_Init(DMA1_Channel5, &DMA_InitStructure);
    
        /* Enable USARTy_DMA1_Channel Transfer complete interrupt */
        DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
    
        /* USARTy_DMA1_Channel enable */
        DMA_Cmd(DMA1_Channel5, ENABLE);
    
    
    
//        USART_InitTypeDef USART_InitStructure; 
//        GPIO_InitTypeDef GPIO_InitStructure;
    
    
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);
        /*
        *  USART1_TX -> PA9 , USART1_RX ->    PA10
        */                
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;          
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
        GPIO_Init(GPIOA, &GPIO_InitStructure);           
    
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;            
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
        GPIO_Init(GPIOA, &GPIO_InitStructure);
    
        USART_InitStructure.USART_BaudRate = 230400;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    
        USART_Init(USART1, &USART_InitStructure); 
        USART_Cmd(USART1, ENABLE);
    
        USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
    
    
    
        //NVIC_InitTypeDef  NVIC_InitStructure;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    
        /* Enable the USARTy_DMA1_IRQn Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
    
#else
    
 
    
        
        /* DMA1 clock enable */
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
        
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);
    
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;          
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
        GPIO_Init(GPIOA, &GPIO_InitStructure);           
    
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;            
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
        GPIO_Init(GPIOA, &GPIO_InitStructure);


        USART_InitStructure.USART_BaudRate = 230400;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode = USART_Mode_Tx;

        USART_Init(USART1, &USART_InitStructure); 
        USART_Cmd(USART1, ENABLE);



    
#endif

    
}




/* -----------------------------------------------------------------------------
USART_Configuration
-------------------------------------------------------------------------------*/
void USART2_init(void)
{

    DMA_InitTypeDef  DMA_InitStructure;
    USART_InitTypeDef USART_InitStructure; 
    GPIO_InitTypeDef GPIO_InitStructure;
    NVIC_InitTypeDef  NVIC_InitStructure;



    //    DMA_InitTypeDef  DMA_InitStructure;

    /* USART2_RX_DMA1_Channel Config */
    DMA_DeInit(DMA1_Channel6);
    DMA_InitStructure.DMA_PeripheralBaseAddr = USART2_DR_Base;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)UART2_Rx_Buffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = sizeof(UART2_Rx_Buffer);
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
#if 0
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
#else
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
#endif
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel6, &DMA_InitStructure);

    /* Enable USARTy_DMA1_Channel Transfer complete interrupt */
    DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);

    /* USARTy_DMA1_Channel enable */
    DMA_Cmd(DMA1_Channel6, ENABLE);



    //    USART_InitTypeDef USART_InitStructure; 
    //    GPIO_InitTypeDef GPIO_InitStructure;


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

    /* Enable USART2 Clock */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); 

    /*
    *  USART2_TX -> PA2 , USART2_RX ->    PA3
    */                
    GPIO_InitStructure.GPIO_Pin = USART2_TxPin;          
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_Init(GPIOA, &GPIO_InitStructure);           

    GPIO_InitStructure.GPIO_Pin = USART2_RxPin;            
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    USART_Init(USART2, &USART_InitStructure); 
    USART_Cmd(USART2, ENABLE);

    USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);




    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

    /* Enable the USARTy_DMA1_IRQn Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
}









/* -----------------------------------------------------------------------------
DMA1 Channel 5 interrupt request.
-------------------------------------------------------------------------------*/
void DMA1_Channel5_IRQHandler(void)
{
  if(DMA_GetITStatus(DMA1_IT_TC5))
  {
    DMA_ClearITPendingBit(DMA1_IT_TC5);

#if 0
  DMA_Cmd(DMA1_Channel5, DISABLE);
  DMA1_Channel5->CNDTR = 10;
  DMA_Cmd(DMA1_Channel5, ENABLE);
#else
    DMA_Cmd(DMA1_Channel5, DISABLE);
    DMA_SetCurrDataCounter(DMA1_Channel5,sizeof(UART1_Rx_Buffer));
    DMA_Cmd(DMA1_Channel5, ENABLE);
#endif

  }
}



/* -----------------------------------------------------------------------------
DMA1 Channel 6 interrupt request.
-------------------------------------------------------------------------------*/
void DMA1_Channel6_IRQHandler(void)
{
  if(DMA_GetITStatus(DMA1_IT_TC6))
  {
    DMA_ClearITPendingBit(DMA1_IT_TC6);


    DMA_Cmd(DMA1_Channel6, DISABLE);
    DMA_SetCurrDataCounter(DMA1_Channel6,sizeof(UART2_Rx_Buffer));
    DMA_Cmd(DMA1_Channel6, ENABLE);

  }
}




#if 0
/* -----------------------------------------------------------------------------
 fetch data from queue
-------------------------------------------------------------------------------*/
#define     BLE_RX_QUEUE_LEN        10


typedef struct{
    UINT8 id;
    UINT16 data;
}ble_rx_queue_data_t;

ble_rx_queue_data_t ble_rx_queue[BLE_RX_QUEUE_LEN];
UINT8 ble_rx_queue_fetch =0;
UINT8 ble_rx_queue_index =0;



void fetch_data_from_DMA_queue(void)
{
    UINT8 localRxBuff[200];
    UINT8 localRxbuffLen=0;
    UINT8 rxLen =0;


    if(DMA_GetCurrDataCounter(DMA1_Channel6) != DMAQueueIndex)
    {
        UINT8 localCurrentDmaQueueIndex = DMA_GetCurrDataCounter(DMA1_Channel6);

        if(DMAQueueIndex > localCurrentDmaQueueIndex)
        {
            /* Normal case */
            rxLen = DMAQueueIndex - localCurrentDmaQueueIndex;
            DMAQueueIndex = localCurrentDmaQueueIndex;

            memcpy(localRxBuff, &UART2_Rx_Buffer[RAMFetchIndex],rxLen);
            RAMFetchIndex +=rxLen;
            localRxbuffLen = rxLen;

        }
        else
        {
            /* over flow*/
            rxLen = DMAQueueIndex;
            memcpy(localRxBuff, &UART2_Rx_Buffer[RAMFetchIndex],rxLen);
            RAMFetchIndex =0;
            localRxbuffLen = rxLen;

            DMAQueueIndex = sizeof(UART2_Rx_Buffer);
            
            rxLen = DMAQueueIndex - localCurrentDmaQueueIndex;
            DMAQueueIndex = localCurrentDmaQueueIndex;
            
            memcpy(&localRxBuff[localRxbuffLen], &UART2_Rx_Buffer[RAMFetchIndex],rxLen);
            RAMFetchIndex +=rxLen;
            localRxbuffLen += rxLen;
            
        }



        for(UINT8 i=0; i<localRxbuffLen; i++)
        {
            if(parsing_rx_data(localRxBuff[i]) == SUCCESS)
            {
                ble_rx_queue[ble_rx_queue_index].id = rx_data.id;
                ble_rx_queue[ble_rx_queue_index].data = rx_data.data;


                ble_rx_queue_index++;

                /* circular */
                if(ble_rx_queue_index == BLE_RX_QUEUE_LEN)
                    ble_rx_queue_index =0;
                
            }
 //           USART_SendData(USART1, localRxBuff[i]);
        }

        
    }



}

#endif





